const express = require('express');
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 3000;

const cors = require('cors');

app.use(cors());
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  next();
});

// 中间件
app.use(express.json());
app.use(express.static('public'));

// 支持的小说网站配置
const supportedSites = {
  'qidian': {
    name: '起点中文网',
    url: 'https://www.qidian.com',
    search: (name) => `https://www.qidian.com/soushu/${name}.html`,
    chapterList: ($) => {
      const chapters = [];
      $('#j-catalogWrap .volume-wrap .volume').each((i, volume) => {
        const volumeTitle = $(volume).find('h3').text().trim();
        chapters.push({ title: volumeTitle, isVolume: true });

        $(volume).find('ul.cf li').each((j, chapter) => {
          chapters.push({
            title: $(chapter).find('a').text().trim(),
            url: $(chapter).find('a').attr('href'),
            isVolume: false
          });
        });
      });
      return chapters;
    },
    chapterContent: async (chapterUrl) => {
      try {
        const response = await axios.get(`https:${chapterUrl}`);
        const $ = cheerio.load(response.data);
        return $('.main-text-wrap .content').text().trim();
      } catch (error) {
        return `获取章节内容失败: ${error.message}`;
      }
    }
  },
  'biquge': {
    name: '笔趣阁',
    url: 'https://www.biquge.com.cn',
    search: (name) => `https://www.biquge.com.cn/search?q=${encodeURIComponent(name)}`,
    chapterList: ($) => {
      const chapters = [];
      $('#list dd').each((i, chapter) => {
        chapters.push({
          title: $(chapter).find('a').text().trim(),
          url: $(chapter).find('a').attr('href'),
          isVolume: false
        });
      });
      return chapters;
    },
    chapterContent: async (chapterUrl, novelUrl) => {
      try {
        const response = await axios.get(`${novelUrl}${chapterUrl}`);
        const $ = cheerio.load(response.data);
        return $('#content').text().trim();
      } catch (error) {
        return `获取章节内容失败: ${error.message}`;
      }
    }
  }
};

// 路由：搜索小说
app.post('/api/search', async (req, res) => {
  const { novelName, site = 'qidian' } = req.body;

  if (!novelName) {
    return res.status(400).json({ error: '小说名称不能为空' });
  }

  if (!supportedSites[site]) {
    return res.status(400).json({ error: '不支持的网站' });
  }

  try {
    const siteConfig = supportedSites[site];
    const searchUrl = siteConfig.search(novelName);
    const response = await axios.get(searchUrl);
    const $ = cheerio.load(response.data);

    const results = [];
    // 根据不同网站解析搜索结果
    if (site === 'qidian') {
      $('.book-img-text li').each((i, el) => {
        results.push({
          title: $(el).find('.book-mid-info h4 a').text().trim(),
          url: $(el).find('.book-mid-info h4 a').attr('href'),
          author: $(el).find('.author a').eq(0).text().trim(),
          update: $(el).find('.update span').text().trim(),
          site: site
        });
      });
    } else if (site === 'biquge') {
      $('#main .result-item').each((i, el) => {
        results.push({
          title: $(el).find('.result-game-item-title a').text().trim(),
          url: $(el).find('.result-game-item-title a').attr('href'),
          author: $(el).find('.result-game-item-info-tag').eq(0).find('span').eq(1).text().trim(),
          update: $(el).find('.result-game-item-info-tag').eq(2).find('span').eq(1).text().trim(),
          site: site
        });
      });
    }

    res.json({ results });
  } catch (error) {
    res.status(500).json({ error: `搜索失败: ${error.message}` });
  }
});

// 路由：获取章节列表
app.post('/api/chapters', async (req, res) => {
  const { novelUrl, site = 'qidian' } = req.body;

  if (!novelUrl) {
    return res.status(400).json({ error: '小说URL不能为空' });
  }

  if (!supportedSites[site]) {
    return res.status(400).json({ error: '不支持的网站' });
  }

  try {
    const siteConfig = supportedSites[site];
    const response = await axios.get(novelUrl.includes('http') ? novelUrl : `${siteConfig.url}${novelUrl}`);
    const $ = cheerio.load(response.data);

    const chapters = siteConfig.chapterList($);
    res.json({ chapters, novelUrl });
  } catch (error) {
    res.status(500).json({ error: `获取章节列表失败: ${error.message}` });
  }
});

// 路由：爬取小说内容
app.post('/api/crawl', async (req, res) => {
  const { novelUrl, site = 'qidian', startChapter = 0, endChapter } = req.body;

  if (!novelUrl) {
    return res.status(400).json({ error: '小说URL不能为空' });
  }

  if (!supportedSites[site]) {
    return res.status(400).json({ error: '不支持的网站' });
  }

  try {
    // 先获取章节列表
    const siteConfig = supportedSites[site];
    const response = await axios.get(novelUrl.includes('http') ? novelUrl : `${siteConfig.url}${novelUrl}`);
    const $ = cheerio.load(response.data);

    const chapters = siteConfig.chapterList($);
    const novelTitle = $('h1').text().trim() || $('#info h1').text().trim() || '未知小说';

    // 确定要爬取的章节范围
    const validChapters = chapters.filter(ch => !ch.isVolume);
    const startIdx = Math.max(0, parseInt(startChapter) || 0);
    const endIdx = Math.min(validChapters.length - 1, parseInt(endChapter) || validChapters.length - 1);

    if (startIdx > endIdx) {
      return res.status(400).json({ error: '起始章节不能大于结束章节' });
    }

    // 开始爬取
    const novelContent = [];
    for (let i = startIdx; i <= endIdx; i++) {
      const chapter = validChapters[i];
      try {
        const content = await siteConfig.chapterContent(chapter.url, novelUrl);
        novelContent.push({
          title: chapter.title,
          content: content,
          wordCount: content.length
        });

        // 每爬取10章稍微延迟一下，避免请求过于频繁
        if (i % 10 === 0) {
          await new Promise(resolve => setTimeout(resolve, 1000));
        }
      } catch (error) {
        novelContent.push({
          title: chapter.title,
          content: `获取失败: ${error.message}`,
          wordCount: 0
        });
      }
    }

    res.json({
      title: novelTitle,
      chapters: novelContent,
      totalChapters: novelContent.length,
      totalWords: novelContent.reduce((sum, ch) => sum + ch.wordCount, 0)
    });
  } catch (error) {
    res.status(500).json({ error: `爬取失败: ${error.message}` });
  }
});

// 路由：下载小说
app.post('/api/download', async (req, res) => {
  const { title, chapters } = req.body;

  if (!title || !chapters) {
    return res.status(400).json({ error: '参数不完整' });
  }

  try {
    // 创建小说文本内容
    let novelText = `《${title}》\n\n`;
    chapters.forEach(chapter => {
      novelText += `${chapter.title}\n\n${chapter.content}\n\n`;
    });

    // 创建临时文件
    const fileName = `${title}_${Date.now()}.txt`;
    const filePath = path.join(__dirname, 'downloads', fileName);

    // 确保下载目录存在
    if (!fs.existsSync(path.join(__dirname, 'downloads'))) {
      fs.mkdirSync(path.join(__dirname, 'downloads'));
    }

    // 写入文件
    fs.writeFileSync(filePath, novelText, 'utf8');

    // 发送文件
    res.download(filePath, `${title}.txt`, (err) => {
      if (err) {
        console.error('下载错误:', err);
      }
      // 下载完成后删除临时文件
      fs.unlinkSync(filePath);
    });
  } catch (error) {
    res.status(500).json({ error: `生成下载文件失败: ${error.message}` });
  }
});

// 启动服务器
app.listen(PORT, () => {
  console.log(`小说爬虫服务运行在 http://localhost:${PORT}`);
});